#include "common.h"
#include "pedal.h"
#include "gpio.h"
#include "irq.h"
#include "init.h"
#include "pin_def.h"
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/interrupt.h>

struct pedal_cfg {
	struct init_block init;
	unsigned irq;
};

static trigger_on_fn_t on_fn = NULL;
static trigger_on_fn_t off_fn = NULL;
static void *data = NULL;

static irqreturn_t pedal_handler(int irq, void *dev)
{
	int ret = gpio_get_value(PEDAL_GPIO_ID);	
	if (ret) {
		// rising edge
		PR_INFO("pedal rising, off");
		off_fn(data);
		PR_INFO("rising handled");

	} else {
		// falling edge
		PR_INFO("pedal falling, on");
		on_fn(data);
		PR_INFO("falling handled");
	}

	return IRQ_HANDLED;
}

int setup_pedal_trigger(trigger_on_fn_t _on_fn, trigger_off_fn_t _off_fn, void *_data)
{
	int ret = 0;
	int irq = 0;
	if (on_fn != NULL) {
		return -2;	
	}
	on_fn = _on_fn;
	off_fn = _off_fn;
	data = _data;

	PR_INFO("request pedal gpio (%d, %s)", PEDAL_GPIO_ID, PEDAL_GPIO_NAME);
	ret = request_gpio(PEDAL_GPIO_ID, PEDAL_GPIO_NAME);
	if (ret < 0) {
		PR_ERR("request pedal gpio failed, ret: %d", ret);
		return ret;
	}

	PR_INFO("set pedal gpio (%d, %s) direction to input", PEDAL_GPIO_ID, PEDAL_GPIO_NAME);
	ret = gpio_direction_input(PEDAL_GPIO_ID);
	if (ret != 0) {
		PR_ERR("set pedal gpio to input failed, ret: %d", ret);
		return ret;
	}


	PR_INFO("setup pedal gpio (%d, %s) interrupt", PEDAL_GPIO_ID, PEDAL_GPIO_NAME);
	irq = gpio_to_irq(PEDAL_GPIO_ID);
	ret = setup_threaded_irq(irq, pedal_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "pedal_irq", NULL);
	if (ret < 0) {
			PR_ERR("setup pedal irq failed, ret: %d", ret);
			return ret;
	}
	
	return ret;
}




